﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;
using System.Data;

namespace GestionaleLib.Controller
{
    public class ctrlMagazzino
    {
        #region "Testata"
        #region "Proprietà"
        private Connector Connessione;
        #endregion
        public enum Causale
        {
            CA,
            SC
        }
        public enum Insert
        {
            Successo,
            Errore,
            NonScaricabile
        }
        public enum Edit
        {
            Successo,
            Errore
        }
        public enum Delete
        {
            Successo,
            Errore
        }
        #endregion

        #region "Metodi"
        public ctrlMagazzino()
        {
            Connessione = Connector.Istance();
        }
        /// <summary>
        /// Carica nella tabella magazzino un prodotto con le specifiche di carico\scarico
        /// </summary>
        /// <param name="Prodotto"></param>
        /// <param name="Magazzino"></param>
        /// <returns>ExceptionErroreInserimento</returns>
        public Insert Carica(Magazzino Magazzino)
        {
            try
            {
                string sql = @"
                INSERT INTO Magazzino 
                    VALUES(@Id,@IdProdotto,@Quantita,@Data,@Causale)
                ";
                SqlCeCommand cmd = new SqlCeCommand(sql, Connessione.Connessione);
                cmd.Parameters.AddWithValue("@Id", (Guid)Magazzino.Id);
                cmd.Parameters.AddWithValue("@IdProdotto", Magazzino.Prodotto.Id);
                cmd.Parameters.AddWithValue("@Quantita", (int)Magazzino.Quantita);
                cmd.Parameters.AddWithValue("@Data", (DateTime)Magazzino.Data);
                cmd.Parameters.AddWithValue("@Causale", Causale.CA.ToString());
                cmd.ExecuteNonQuery();
                return Insert.Successo;
            }
            catch
            {
                throw new ExceptionErroreInserimento();
            }
        }
        private bool ProdottoScaricabile(Magazzino Magazzino)
        {
            int Giacenza = Disponibilita(Magazzino.Prodotto);
            int Rimanenza = (Giacenza - Magazzino.Quantita);

            if (Rimanenza == 0)
                return true;
            else if (Rimanenza<1)
                return false;

            return true;
        }
        /// <summary>
        /// Scarica nella tabella magazzino un prodotto con le specifiche di carico\scarico
        /// </summary>
        /// <param name="Prodotto"></param>
        /// <param name="Magazzino"></param>
        /// <returns>ExceptionErroreInserimento</returns>
        public Insert Scarica(Magazzino Magazzino)
        {
            try
            {
                if (!ProdottoScaricabile(Magazzino))
                    return Insert.NonScaricabile;

                string sql = @"
                INSERT INTO Magazzino 
                    VALUES(@Id,@IdProdotto,@Quantita,@Data,@Causale)
                ";
                SqlCeCommand cmd = new SqlCeCommand(sql, Connessione.Connessione);
                cmd.Parameters.AddWithValue("@Id", (Guid)Magazzino.Id);
                cmd.Parameters.AddWithValue("@IdProdotto", Magazzino.Prodotto.Id);
                cmd.Parameters.AddWithValue("@Quantita", (int)Magazzino.Quantita);
                cmd.Parameters.AddWithValue("@Data", (DateTime)Magazzino.Data);
                cmd.Parameters.AddWithValue("@Causale", Causale.SC.ToString());
                cmd.ExecuteNonQuery();
                return Insert.Successo;
            }
            catch (ExceptionErroreInserimento)
            {
                throw new ExceptionErroreInserimento();
            }
        }
        public int GetMinimoGiacenzaProdotto(Prodotto Prodotto)
        {
            string sql = @"
                SELECT MinimoMagazzino FROM Prodotti 
                    WHERE Id='" + Prodotto.Id + "'";
            SqlCeCommand cmd = new SqlCeCommand(sql, Connessione.Connessione);
            return (int)cmd.ExecuteScalar();
        }
        public int QuantitaCaricata(Prodotto Prodotto)
        {
            string sql = @"
                SELECT SUM(Quantita) AS Qta  
                FROM Magazzino
                WHERE IdProdotto='" + Prodotto.Id+"' AND Causale='"+Causale.CA.ToString()+"'";
            SqlCeDataAdapter com = new SqlCeDataAdapter(sql, Connessione.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            int Qta=0;
            if (dt.Rows.Count > 0)
            {
                if (dt.Rows[0]["Qta"].ToString() != "")
                    Qta = (int)(dt.Rows[0]["Qta"]);
            }
            return Qta;
        }
        public int QuantitaScaricata(Prodotto Prodotto)
        {
            string sql = @"
                SELECT SUM(Quantita) AS Qta   
                FROM Magazzino
                WHERE IdProdotto='" + Prodotto.Id + "' AND Causale='" + Causale.SC.ToString() + "'";
            SqlCeDataAdapter com = new SqlCeDataAdapter(sql, Connessione.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            int Qta = 0;
            if (dt.Rows.Count > 0)
            {
                if(dt.Rows[0]["Qta"].ToString()!="")
                    Qta = (int)dt.Rows[0]["Qta"];
            }
            return Qta;
        }
        /// <summary>
        /// Restituisce la quantità effettiva di prodotti in giacenza
        /// </summary>
        /// <param name="Prodotto"></param>
        /// <returns></returns>
        public int Disponibilita(Prodotto Prodotto)
        {
            try
            {
                int QtaCA = QuantitaCaricata(Prodotto);
                int QtaSC = QuantitaScaricata(Prodotto);
                return (int)(QtaCA - QtaSC);
            }
            catch
            {
                throw new ExceptionErroreDuranteCalcoloDisponibilitaMagazzino();
            }
        }
        /// <summary>
        /// Seleziona tutti i prodotti con giacenza in magazzino
        /// </summary>
        /// <returns></returns>
        public List<Magazzino> Seleziona()
        {
            string sql = @"
                SELECT Prodotti.Id, Prodotti.Codice, Prodotti.Descrizione, Magazzino.Quantita, Magazzino.Data, Magazzino.Causale
                FROM Magazzino INNER JOIN
                    Prodotti ON Magazzino.IdProdotto = Prodotti.Id 
            ";
            SqlCeDataAdapter com = new SqlCeDataAdapter(sql, Connessione.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            List<Magazzino> ListaRitorno = new List<Magazzino>();
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow item in dt.Rows)
                {
                    Magazzino Magazzino = new Magazzino();
                    Magazzino.Prodotto = new Prodotto()
                    {
                        Id = (Guid)item["Id"],
                        Codice =(string) item["Codice"],
                        Descrizione =(string) item["Descrizione"],
                    };
                    Magazzino.Causale = item["Causale"].ToString();
                    Magazzino.Data = (DateTime)item["Data"];
                    Magazzino.Quantita = (int)item["Quantita"];
                    ListaRitorno.Add(Magazzino);
                }
                return ListaRitorno;
            }
            return null;
        }
        /// <summary>
        /// Seleziona tutti i prodotti con giacenza in magazzino by IdProdotto
        /// </summary>
        /// <returns></returns>
        public List<Magazzino> Seleziona(Guid IdProdotto)
        {
            string sql = @"
                SELECT Prodotti.Id, Prodotti.Codice, Prodotti.Descrizione, Magazzino.Quantita, Magazzino.Data, Magazzino.Causale,Magazzino.IdProdotto 
                FROM Magazzino INNER JOIN
                    Prodotti ON Magazzino.IdProdotto = Prodotti.Id 
                WHERE Magazzino.IdProdotto='"+IdProdotto+"'";

            SqlCeDataAdapter com = new SqlCeDataAdapter(sql, Connessione.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            List<Magazzino> ListaRitorno = new List<Magazzino>();
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow item in dt.Rows)
                {
                    Magazzino Magazzino = new Magazzino();
                    Magazzino.Prodotto = new Prodotto()
                    {
                        Id = (Guid)item["Id"],
                        Codice = (string)item["Codice"],
                        Descrizione = (string)item["Descrizione"],
                    };
                    Magazzino.Causale = item["Causale"].ToString();
                    Magazzino.Data = (DateTime)item["Data"];
                    Magazzino.Quantita = (int)item["Quantita"];
                    ListaRitorno.Add(Magazzino);
                }
                return ListaRitorno;
            }
            return null;
        }
        /// <summary>
        /// Seleziona tutti i prodotti con giacenza in magazzino con ricerca per contiene (codice,descrizione)
        /// </summary>
        /// <returns></returns>
        public List<Magazzino> Seleziona(string Valore)
        {
            string sql = @"
                SELECT Prodotti.Id, Prodotti.Codice, Prodotti.Descrizione, Magazzino.Quantita, Magazzino.Data, Magazzino.Causale
                FROM Magazzino INNER JOIN 
                    Prodotti ON Magazzino.IdProdotto = Prodotti.Id 
                WHERE (Prodotti.Codice LIKE '%"+Valore+"%' OR Prodotti.Descrizione LIKE '%" + Valore + "%')";

            SqlCeDataAdapter com = new SqlCeDataAdapter(sql, Connessione.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            List<Magazzino> ListaRitorno = new List<Magazzino>();
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow item in dt.Rows)
                {
                    Magazzino Magazzino = new Magazzino();
                    Magazzino.Prodotto = new Prodotto()
                    {
                        Id = (Guid)item["Id"],
                        Codice = (string)item["Codice"],
                        Descrizione = (string)item["Descrizione"],
                    };
                    Magazzino.Causale = item["Causale"].ToString();
                    Magazzino.Data = (DateTime)item["Data"];
                    Magazzino.Quantita = (int)item["Quantita"];
                    ListaRitorno.Add(Magazzino);
                }
                return ListaRitorno;
            }
            return null;
        }
        #endregion
    }
}
